/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gui;

import domain.player.*;
import domain.player.ai.*;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.TitledBorder;
import main.AppConstants;

/**
 * AI settings dialog.
 *
 * It allows you to change the AI of the players that are controlled by the
 * computer during a game. It does not pause the game, so it is only really
 * useful when you want to change the ai settings when playing Human vs Computer,
 * or when the Computer is taking too long to decide on a move.
 */
public class SetupAIDialog extends JDialog {

	private List<Player> players = new ArrayList<Player>(2);
	private JRadioButton jcbMiniMax1;
	private JRadioButton jcbMiniMax2;
	private JRadioButton jcbHashMap1;
	private JRadioButton jcbHashMap2;
        private JRadioButton jcbMinMax1;
        private JRadioButton jcbMinMax2;
	private JSpinner jspnSearch1;
	private JSpinner jspnSearch2;
	private JPanel playerPanel1;
	private JPanel playerPanel2;
	private Font headerFont = new Font(Font.DIALOG, Font.BOLD, 14);
	private int depthOfSearch = 9;

	public SetupAIDialog(Player player1, Player player2) {
		if (player1 != null) {
			players.add(player1);
		}
		if (player2 != null) {
			players.add(player2);
		}

		createDialog();
	}

	/** Create the dialog */
	public void createDialog() {
		setTitle("AI Settings");
		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		setModal(true);

		// Add components
		Box box = Box.createVerticalBox();

		JPanel playerPanel = new JPanel();
		if (!players.isEmpty()) {
			playerPanel.add(createPlayerAIPanels());
			box.add(createAboutText());
			box.add(playerPanel);
		} else {
			playerPanel.add(createErrorMessage());
			box.add(playerPanel);
		}

		getContentPane().add(box);
		getContentPane().add(createOKButton(), BorderLayout.SOUTH);

		// resize and make visible.
		pack();
		setLocationRelativeTo(null);
		setResizable(false);

		setVisible(true);
	}

	/** Error message when no Players have been created */
	private JPanel createErrorMessage() {
		String errorMsg = "<html>No players have been created yet.<br/>"
				+ "You can't change the AI of players that doesn't exist.</html>";

		JPanel pane = new JPanel();
		pane.add(new JLabel(errorMsg));
		pane.setBorder(BorderFactory.createLineBorder(Color.RED, 2));
		return pane;
	}

	/** Creates a panel with some info text about the different settings */
	private JPanel createAboutText() {
		String topText = "<HTML><p>This was mostly added for testing purposes.<br>"
				+ "Press OK to confirm, close the window to cancel. <p/>"
				+ "<br><center><i>AI Types</i></center>"
				+ "<p><u>HashMap</u><br>"
				+ "Saves all the moves the other player does in a HashMap together with the gamestate/gameboard and assumes they are \"optimal\" moves."
				+ " It then looks up the current gamestate when it will make a move and repeats the move that was saved. If it can't find the current gameboard, it makes a random move.</p>"
				+ "<p><br><u>MiniMax</u><br>"
				+ "Implements the algorithm minimax, where the computer will try to max out his points every move. The points are calculated with a simple function that counts how many 2- and 3-in-a-rows it has against how many the opponent has.<br/>"
				+ " <br><b>Search depth</b> is how many moves ahead the computer will look, at zero he will simply evaluate the next move he can make, at 1 he will also consider the next move the other player can do and so on.</p>"
				+ "</HTML>";

		JPanel box = new JPanel();

		JLabel top = new JLabel(topText);
		top.setPreferredSize(new Dimension(400, 250));

		box.add(top);
		box.setBorder(new TitledBorder("About"));

		return box;
	}

	/** creates a box with panels for the players */
	private Box createPlayerAIPanels() {
		// Player columns:
		Box playerGrid = Box.createHorizontalBox();

		Iterator it = players.iterator();
		for (int i = 0; it.hasNext(); i++) {
			playerGrid.add(createAIPlayerPanel((Player) it.next(), i));
		}


		return playerGrid;
	}

	/** creates a penal for one player  */
	private JPanel createAIPlayerPanel(Player p, int index) {
		JPanel pane = new JPanel(new GridLayout(0, 1));

		pane.setAlignmentY(TOP_ALIGNMENT);

		// border
		TitledBorder border = new TitledBorder("Player: " + p.getName());
		border.setTitleFont(headerFont);
		pane.setBorder(border);

		// content
		if (p.getType() != PlayerType.COMPUTER) {
			border.setTitleColor(Color.GRAY);
			pane.add(new JLabel("<html><p>  " + p.getName() + " is not controlled by the computer.</p></html>"));

			pane.setMaximumSize(new Dimension(200, 100));
			pane.setPreferredSize(new Dimension(200, 100));
		} else {
			pane.setPreferredSize(new Dimension(300, 150));

			pane.add(createAIChoice((Computer) p, index));
			pane.add(createSearchDepthPanel(index, (Computer) p));
		}

		return pane;
	}

	/** Creates some radiobuttons for the dialog and adds them to a panel. */
	private JPanel createAIChoice(Computer p, int index) {
		final int i = index;
		JPanel pane = new JPanel();

		pane.setBorder(new TitledBorder("Type of AI"));

		JRadioButton minimax = new JRadioButton("MiniMax");
		JRadioButton hashmap = new JRadioButton("HashMap");
                JRadioButton minimaxWAB = new JRadioButton("MiniMax2");

		// Group radio buttons:
		ButtonGroup groupTypeP1 = new ButtonGroup();
		groupTypeP1.add(minimax);
                groupTypeP1.add(minimaxWAB);
		groupTypeP1.add(hashmap);

                minimaxWAB.setVisible(true);

		// The current ai-type:
		if (p.getAIType() == AI.AI_MINIMAX) {
			minimax.setSelected(true);
		} else if(p.getAIType() == AI.AI_HASHMAP){
			hashmap.setSelected(true);
		} else{
                    minimaxWAB.setSelected(true);
                }

		// Add radio buttons:
		pane.add(minimax);
                pane.add(minimaxWAB);
		pane.add(hashmap);


		if (index == 0) {
			jcbMiniMax1 = minimax;
			jcbHashMap1 = hashmap;
                        jcbMinMax1 = minimaxWAB;
		} else {
			jcbMiniMax2 = minimax;
			jcbHashMap2 = hashmap;
                        jcbMinMax2 = minimaxWAB;
		}

		return pane;
	}

	/** Creates a JPanel with a spinner for changing how many moves ahead the computer will look */
	private JPanel createSearchDepthPanel(int index, Computer p) {
		JPanel pane = new JPanel();

		pane.setBorder(new TitledBorder(" MiniMax Option "));

		SpinnerModel searchModel = new SpinnerNumberModel(p.getMovesAhead(), 0, 15, 1);
		JSpinner spinner = new JSpinner(searchModel);
		JLabel label = new JLabel("Search Depth (0-15): ");
		label.setLabelFor(spinner);

		pane.add(label);
		pane.add(spinner);

		if (index == 0) {
			jspnSearch1 = spinner;
		} else {
			jspnSearch2 = spinner;
		}

		return pane;
	}

	/** Adds the OK button component to the dialog */
	private JPanel createOKButton() {
		JPanel buttonPanel = new JPanel(new FlowLayout());
		buttonPanel.setBackground(AppConstants.COLOR_PANEL_BACKGROUND);
		buttonPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, AppConstants.COLOR_PANEL_BORDER));

		// OK button:
		JButton jBtnOK = new JButton("OK");
		jBtnOK.setBackground(AppConstants.COLOR_PANEL_BACKGROUND);
		jBtnOK.addActionListener(new ActionListener() {

			/**
			 * Button listener: OK
			 * If there's valid data = create players otherwise show error dialog
			 */
			@Override
			public void actionPerformed(ActionEvent e) {
				setAI();
				dispose();
			}
		});
		buttonPanel.add(jBtnOK);

		return buttonPanel;
	}

	/** Makes the changes happen, if any setting has been changed. */
	private void setAI() {
		Computer player;
		if (players.isEmpty()) {
			return;
		}
                try{
		changeAI(players.get(0), jcbHashMap1, jcbMinMax1, jcbMiniMax1, (Integer) jspnSearch1.getValue());
		changeAI(players.get(1), jcbHashMap2, jcbMinMax2, jcbMiniMax2, (Integer) jspnSearch2.getValue());
                } catch(NullPointerException ex){
                    
                }
	}

	private void changeAI(Player p, JRadioButton hashmap, JRadioButton minMax, JRadioButton miniMax, int ply) {
		Computer player;
		if( p.getType() == PlayerType.COMPUTER ) {
                    System.out.println("changing");
			player = (Computer) p;

			if( player.getAIType() == AI.AI_MINIMAX ) {
				if( hashmap.isSelected() ) {
                                    System.out.println("set hashmap");
					player.setAIType(AI.AI_HASHMAP, true, false, 7);
				} else if( minMax.isSelected() ) {
                                    System.out.println("set alfabeta");
					player.setAIType(AI.AI_MINMAX, true, false, ply);
				} else {
					player.setPly(ply);
				}
			} else
				if( (player.getAIType() == AI.AI_HASHMAP) ) {
					if( miniMax.isSelected() ) {
                                            System.out.println("set minimax");
						player.setAIType(AI.AI_MINIMAX, true, false, ply);
					} else if( minMax.isSelected() ) {
                                            System.out.println("set alfabeta");
						player.setAIType(AI.AI_MINMAX, true, false, ply);
					}
				}
		}
	}

	/*
	// Makes the changes happen, if any setting has been changed.
	private void setAI() {
		Computer player;
		if( players.isEmpty() ) {
			return;
		}

		if( players.get(0).getType() == PlayerType.COMPUTER ) {
			player = ((Computer) players.get(0));

			if( player.getAIType() == AI.AI_MINMAX ) {
				if( jcbHashMap1.isSelected() ) {
					player.setAIType(AI.AI_HASHMAP);
				} else
					if( jcbMinMax1.isSelected() ) {
						player.setAIType(AI.AI_MINIMAX);
					} else {
						player.setPly((Integer) jspnSearch1.getValue());
					}
			} else
				if( (player.getAIType() == AI.AI_HASHMAP) ) {
					if( jcbMiniMax1.isSelected() ) {
						player.setAIType(AI.AI_MINMAX);
					} else if( jcbMinMax1.isSelected() ) {
						player.setAIType(AI.AI_MINIMAX);
					}
				}
		}

		if( players.get(1).getType() == PlayerType.COMPUTER ) {
			player = ((Computer) players.get(1));

			if( player.getAIType() == AI.AI_MINMAX ) {
				if( jcbHashMap2.isSelected() ) {
					player.setAIType(AI.AI_HASHMAP);
				} else if( jcbMinMax2.isSelected() ) {
					player.setAIType(AI.AI_MINIMAX);
				} else {
					player.setPly((Integer) jspnSearch2.getValue());
				}
			} else
				if( (player.getAIType() == AI.AI_HASHMAP) ) {
					if( jcbMiniMax2.isSelected() ) {
						player.setAIType(AI.AI_MINMAX);
					} else if( jcbMinMax2.isSelected() ) {
						player.setAIType(AI.AI_MINIMAX);
					}
				}
		}
	}
	*/

}